using System;
using System.BusinessObjects.Data;
using System.Data;
using System.BusinessObjects.Validation;
using Iesi.Collections.Generic;
using Blazing.BusinessObjects.Tagging;
using System.Collections.Generic;
using Blazing.BusinessObjects.Widgets;

namespace Blazing.BusinessObjects.Cms
{
    [Serializable]
    public class Contentpage : DataObject<Contentpage>
    {
        #region Properties
        public virtual int ID
        {
            get { return GetValue<int>("ID"); }
            set
            {
                BeginEdit();
                SetValue("ID", value);
            }
        }

        [ValidationNotEmpty]
        public virtual string Name
        {
            get { return GetValue<string>("Name"); }
            set
            {
                BeginEdit();
                SetValue("Name", value);
            }
        }

        [ValidationNotEmpty]
        public virtual string PageTitle
        {
            get { return GetValue<string>("PageTitle"); }
            set
            {
                BeginEdit();
                SetValue("PageTitle", value);
            }
        }

        public virtual string CreatedBy
        {
            get { return GetValue<string>("CreatedBy"); }
            set
            {
                BeginEdit();
                SetValue("CreatedBy", value);
            }
        }

        public virtual string ModifiedBy
        {
            get { return GetValue<string>("ModifiedBy"); }
            set
            {
                BeginEdit();
                SetValue("ModifiedBy", value);
            }
        }

        public virtual string Content
        {
            get { return GetValue<string>("Content"); }
            set
            {
                BeginEdit();
                SetValue("Content", value);
            }
        }

        [NonSerialized]
        Contentpage _contentPageParent;
        public virtual Contentpage ParentPage
        {
            get
            {
                return _contentPageParent;
            }
            set
            {
                BeginEdit();
                _contentPageParent = value;
            }
        }

        [NonSerialized]
        Blazing.BusinessObjects.Cms.Site _site;
        public virtual Blazing.BusinessObjects.Cms.Site Site
        {
            get
            {
                return _site;
            }
            set
            {
                BeginEdit();
                _site = value;
            }
        }

        [NonSerialized]
        private ISet<MenuItem> _menuItems = new HashedSet<MenuItem>();
        public virtual ISet<MenuItem> MenuItems
        {
            get
            {
                return _menuItems;
            }
            set
            {
                BeginEdit();
                _menuItems = value;
            }
        }

        [NonSerialized]
        private ISet<TaxonomyTag> _contentpageTaxonomyTags = new HashedSet<TaxonomyTag>();
        public virtual ISet<TaxonomyTag> TaxonomyTags
        {
            get
            {
                return _contentpageTaxonomyTags;
            }
            set
            {
                BeginEdit();
                _contentpageTaxonomyTags = value;
            }
        }

        [NonSerialized]
        private IList<PageWidget> _pageWidgets = new List<PageWidget>();
        public virtual IList<PageWidget> Widgets
        {
            get
            {
                return _pageWidgets;
            }
            set
            {
                BeginEdit();
                _pageWidgets = value;
            }
        }

        [NonSerialized]
        private ISet<FeedbackItem> _feedbackItems = new HashedSet<FeedbackItem>();
        public virtual ISet<FeedbackItem> FeedbackItems
        {
            get
            {
                return _feedbackItems;
            }
            set
            {
                BeginEdit();
                _feedbackItems = value;
            }
        }

        [ValidationNotEmpty]
        public virtual string Url
        {
            get { return GetValue<string>("Url"); }
            set
            {
                BeginEdit();
                SetValue("Url", value);

            }
        }

        public virtual string PermaLink
        {
            get { return GetValue<string>("PermaLink"); }
            set
            {
                BeginEdit();
                SetValue("PermaLink", value);
            }
        }

        public virtual bool IsHttps
        {
            get { return GetValue<bool>("IsHttps"); }
            set
            {
                BeginEdit();
                SetValue("IsHttps", value);
            }
        }

        public virtual bool IsActive
        {
            get { return GetValue<bool>("IsActive", true); }
            set
            {
                BeginEdit();
                SetValue("IsActive", value);
            }
        }

        public virtual string Comments
        {
            get { return GetValue<string>("Comments"); }
            set
            {
                BeginEdit();
                SetValue("Comments", value);
            }
        }

        public virtual string MetaDescription
        {
            get { return GetValue<string>("MetaDescription"); }
            set
            {
                BeginEdit();
                SetValue("MetaDescription", value);
            }
        }

        public virtual string MetaKeywords
        {
            get { return GetValue<string>("MetaKeywords"); }
            set
            {
                BeginEdit();
                SetValue("MetaKeywords", value);
            }
        }

        /// <summary>
        /// An additional literal that will get rendered into the head tag of the page,
        /// so this is a generic field that could be used for any type of extension requiring access to the header
        /// </summary>
        public virtual string MetaExtra
        {
            get { return GetValue<string>("MetaExtra"); }
            set
            {
                BeginEdit();
                SetValue("MetaExtra", value);
            }
        }

        [NonSerialized]
        PageType _pagetype;
        public virtual PageType PageType
        {
            get
            {
                return _pagetype;
            }
            set
            {
                BeginEdit();
                _pagetype = value;
            }
        }

        [NonSerialized]
        Masterpage _masterpage;
        public virtual Masterpage Masterpage
        {
            get
            {
                return _masterpage;
            }
            set
            {
                BeginEdit();
                _masterpage = value;
            }
        }

        [NonSerialized]
        Theme _theme;
        public virtual Theme Theme
        {
            get
            {
                return _theme;
            }
            set
            {
                BeginEdit();
                _theme = value;
            }
        }

        public virtual DateTime RowStamp
        {
            get { return GetValue<DateTime>("RowStamp"); }
            set
            {
                SetValue("RowStamp", value);
            }
        }

        public virtual DateTime CreatedDate
        {
            get { return GetValue<DateTime>("CreatedDate"); }
            set
            {
                SetValue("CreatedDate", value);
            }
        }

        #endregion

        public Contentpage()
        {
            OnSaving += Contentpage_OnSaving;
        }

        void Contentpage_OnSaving(object sender, EventArgs e)
        {
            if (IsNull("CreatedDate"))
                CreatedDate = DateTime.Now;
        }

        /// <summary>
        /// Finds the root page in a page hierarchy
        /// </summary>
        public static Contentpage FindRootPage(Contentpage anyPage)
        {
            if (anyPage.ParentPage == null)
                return anyPage;
            else
                return FindRootPage(anyPage.ParentPage);
        }

        protected override void AddValidationRules()
        {
            validationRules.Add(new ValidationRule(GeneralAssertionTemplate.IsNotNull(this, "Theme")));
            validationRules.Add(new ValidationRule(GeneralAssertionTemplate.IsNotNull(this, "Masterpage")));
            validationRules.Add(new ValidationRule(GeneralAssertionTemplate.IsNotNull(this, "PageType")));
            validationRules.Add(new ValidationRule(GeneralAssertionTemplate.IsNotNull(this, "Site")));
            validationRules.Add(new ValidationRule(ValidationRuleCanNotSetParentToSelf()));

            
        }

        public virtual ValidatorTemplate ValidationRuleCanNotSetParentToSelf()
        {
            System.Reflection.PropertyInfo parentInfo = GetType().GetProperty("ParentPage");
            ValidatorTemplate parentIsNotSelf = delegate(out string propName, out string message)
            {
                propName = "ParentPage";
                bool retval = true;
                message = string.Empty;
                object curVal = parentInfo.GetValue(this, null);
                if (curVal != null)
                {
                    if (((Contentpage)curVal).ID == ID)
                    {
                        message = string.Format("Content page's parent can not be set to itself  #{0}", ID);
                        retval = false;
                    }
                }
                return retval;
            };

            return parentIsNotSelf;
        }

    }
}
